import java.net.*;
import java.io.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.* ;
import java.util.*;

public class ChatroomClient extends JFrame implements ActionListener, MouseListener {

    JTextArea	msgBoard	= new JTextArea( );
    JTextField	msgToSend	= new JTextField( 30);
    JLabel	lbMsg		= new JLabel("Public Message" );
    JPanel	plSouth		= new JPanel( );
    JPanel	plNames		= new JPanel();
    JLabel	lbName		= new JLabel("Name");
    JTextField	tfName		= new JTextField( 5 );
    Container	c		= null;

    ObjectOutputStream sout 	= null;
    Graphics		g	= null;
    boolean		isPrivate = false ;

    public ChatroomClient ( ) {
	c = getContentPane( );
	plNames.setBorder ( new TitledBorder( "Client List"));
	plNames.setPreferredSize(new Dimension(100, 500) );
	msgToSend.addActionListener( this ); 
	tfName   .addActionListener( this ); 
	lbMsg    .addMouseListener( this ); 
	plNames  .addMouseListener( this ); 
	plSouth.add( lbName); plSouth.add( tfName);
	plSouth.add( lbMsg ); plSouth.add( msgToSend );
	c.add( plSouth, BorderLayout.SOUTH );
	c.add( msgBoard, BorderLayout.CENTER );
	c.add( plNames, BorderLayout.EAST);

	setSize(700, 500);
	setVisible( true );

	g = plNames.getGraphics();
 
    }
    public void mouseClicked(MouseEvent e) {
        Object obj = e.getSource();
        if ( obj == lbMsg ) {
	  isPrivate = ! isPrivate;
	  lbMsg.setForeground( isPrivate? Color.red : Color.black );
	  lbMsg.setText ( isPrivate? "Private Message" : "Public Message");
       }
       if ( obj == plNames ) {
	  checkSelected(e.getX(), e.getY() );

       }
    }
    public void mouseEntered(MouseEvent e) { } 
    public void mouseExited(MouseEvent e)  { }
    public void mousePressed(MouseEvent e) { }
    public void mouseReleased(MouseEvent e) { }

    public void paint( Graphics g) {
	super.paint( g );
    }

    public void actionPerformed ( ActionEvent e ) {
       Object obj = e.getSource( );
       if ( obj == msgToSend ) {
	  try { sout.writeObject( msgToSend.getText() ); } catch (IOException e2) { e2.printStackTrace(); }
	   msgToSend.setText("");
       }

    } 
    public static void main ( String args[] ) {
	ChatroomClient client = new ChatroomClient( ) ;

	Socket sk = null;


	client.printClients() ;

	try {
	   sk = new Socket("sleipnir.cs.csubak.edu", 55667 );
	   new Thread ( new Receiver( sk , client.msgBoard ) ).start( );

	   client.sout = new ObjectOutputStream ( sk.getOutputStream() );

/*
	   while ( true ) {
		msg = ScreenIO.promptForString("Enter your message to send: " );
		sout.writeObject( msg ) ;
	   }
*/
	} catch (IOException e) { e.printStackTrace(); }

    }

    static int yStart = 40, yIncrement = 20, xStart = 10;

    void printClients( ) {

	 // Replace the following 2 lines by actual code.
	 Message msg = new Message( Message.LOGIN, "Test", "...", "Albert; Cyndy;Bryan;John; Pierce;Rob");
	 Vector<String> v = msg.toVector();


	 g.setColor( plNames.getBackground() );
	 g.fillRect( xStart, yStart - 20, 100 - xStart, 500 - yStart - 50);
	 g.setColor( Color.blue );
	 for ( int i = 0; i < v.size(); i ++ )
		 g.drawString( v.get(i), xStart, yStart + i * yIncrement);
    }

    void checkSelected( int x, int y )  {
	 System.out.printf("Client list clicked at point (%d, %d)\n", x, y);
    }
}

class Receiver implements Runnable {

   Socket 		sk = null;
   ObjectInputStream	sin = null;
   JTextArea		msgBoard = null;
   public Receiver ( Socket sk, JTextArea a ) {
      try {
	this.sk = sk; msgBoard = a;
	sin = new ObjectInputStream ( sk.getInputStream() ) ;
      } catch (IOException e ) { e.printStackTrace(); }
   }

   public void run ( ) {
        Object obj = null;
	try { 
	  while ( true ) {             
	    obj = sin.readObject() ;  // read will wait until a object is written to this receiver from server.
	    // System.out.println( (String ) obj );
	   msgBoard.append( (String) obj + '\n' );
	  }
        } catch ( IOException e ) { e.printStackTrace( ) ; }
	catch ( ClassNotFoundException e2) { e2.printStackTrace(); }

	try { sk.close() ; } catch ( IOException e ) { }
   }
}
